﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace snat.model {
    public abstract class OverlayNode : BaseNode {
        /// <summary>
        /// Static event thrown when all nodes reset
        /// </summary>
        public static event algorithmDelegate ResetOverlay;
        /// <summary>
        /// Resets all overlay nodes, throwing ResetOverlay event
        /// </summary>
        public static void TriggerOverlayReset() {
            if (ResetOverlay != null) ResetOverlay();
        }

        private List<Edge> overlayInEdges = new List<Edge>();
        /// <summary>
        /// List of overlay edges where this node is a target
        /// </summary>
        public override List<Edge> OverlayInEdges {
            get { return overlayInEdges; } //should just be return but left as reminder
        }
        /// <summary>
        /// Current overlay degree of this node
        /// </summary>
        public override int OverlayInDegree {
            get {
                return overlayInEdges.Count;
            }
        }
        /// <summary>
        /// Current overlay out degree of this node
        /// </summary>
        public override int OverlayOutDegree {
            get {
                return overlayOutEdges.Count;
            }
        }
        /// <summary>
        /// Current overlay degree of this node
        /// </summary>
        public override int OverlayDegree {
            get {
                return overlayInEdges.Count + overlayOutEdges.Count;
            }
        }
        
        private List<Edge> overlayOutEdges = new List<Edge>();
        /// <summary>
        /// List of overlay edges where this node is a source
        /// </summary>
        public override List<Edge> OverlayOutEdges {
            get { return overlayOutEdges; }
        }

        /// <summary>
        /// Event thrown when an overlay in edge is added to the node
        /// </summary>
        public event edgeAdded OverlayInEdgeAdded;
        /// <summary>
        /// Adds an overlay in edge to the node and throws OverlayInEdgeAdded event
        /// </summary>
        /// <param name="e"></param>
        public void TriggerOverlayInEdgeAdded(Edge e) {
            if (OverlayInEdgeAdded != null) OverlayInEdgeAdded(e, this);
        }
        /// <summary>
        /// Event thrown when an overlay out edge is added to the node
        /// </summary>
        public event edgeAdded OverlayOutEdgeAdded;
        /// <summary>
        /// Adds an overlay out edge to the node and throws OverlayOutEdgeAdded event
        /// </summary>
        /// <param name="e"></param>
        public void TriggerOverlayOutEdgeAdded(Edge e) {
            if (OverlayOutEdgeAdded != null) OverlayOutEdgeAdded(e, this);
        }

        public OverlayNode(int _id, string _name)
            : base(_id, _name) {
                OverlayOutEdgeAdded += AddOverlayOutEdge;
                OverlayInEdgeAdded += AddOverlayInEdge;
                ResetOverlay += ResetEdges;
        }

        private void ResetEdges() {
            overlayInEdges.Clear();
            overlayOutEdges.Clear();
        }

        private void AddOverlayOutEdge(Edge e, BaseNode n) {
            overlayOutEdges.Add(e);
        }
        private void AddOverlayInEdge(Edge e, BaseNode n) {
            overlayInEdges.Add(e);
        }
    }
}